//
// Created by Suzhen on 2017/2/24.
//

#ifndef ORIONV2_ABSTRACTASYNCSTREAM_H
#define ORIONV2_ABSTRACTASYNCSTREAM_H

#include "Orion.h"
#include "AsyncEventGenerator.h"
#include "IOBehavior.h"
#include "IOBuffer.h"

ORION_V2_NAMESPACE_BEGIN
        
        class AbstractAsyncStream : public EnhanceSupport::UserDataSupport,
                                    public EnhanceSupport::MRCSupport {
            
            friend class AsyncEventGenerator;
        
        protected:
            
            struct IOEvent {
                constexpr static int READABLE = 1;
                constexpr static int WRITABLE = 2;
                constexpr static int DISCONNECT = 4;
                constexpr static int NONE = 0;
            };
            
            struct AsyncPollData {
                //运行 pollCtx 的 loop 的线程 id
                ThreadId tid;
                //file descriptor
                FdType fd{0};
                //poll event flag
                EventFlag events{0};
                //system poll context
                PollContext pollCtx;
            };
        
        public:
            
            //virtual destructor
            virtual ~AbstractAsyncStream();
            
            //constructor
            explicit AbstractAsyncStream(const IOBehavior &ioBehavior);
            
            AbstractAsyncStream(const AbstractAsyncStream &) = delete;
            
            AbstractAsyncStream &operator=(const AbstractAsyncStream &) = delete;
            
            AbstractAsyncStream(AbstractAsyncStream &&) = delete;
            
            AbstractAsyncStream &operator=(AbstractAsyncStream &&) = delete;
            
            /**
             * 激活Stream的IO
             * @param e @see EventFlag , IOEvent
             */
            virtual void activate(EventFlag e) = 0;
            
            /**
             * 初始化 AsyncStream 将其绑定到一个事件发生器上
             * @param gen 事件发生器
             */
            virtual void attach(AsyncEventGenerator *gen);
            
            virtual bool isAttached();
            
            /**
             * Stream 是否已经关闭
             * @return bool
             */
            virtual bool isClosed() = 0;
            
            /**
             * Stream 是否正在关闭中
             * @return bool
             */
            virtual bool isClosing() = 0;
            
            /**
             * 实现异步发送,数据发送完成之后回调
             */
            virtual Future<bool> sendAsync(IOBuffer &&dataBuffer) = 0;
            
            /**
             * 请求异步关闭
             * <h2>当底层所关联对象被关闭后,此方法才会真正的完成,然后执行 "then" 或者 "get返回"</h2>
             * @return bool_future
             */
            virtual Future<bool> closeAsync() = 0;
        
        protected:
            /**
             * Stream 进行 IO 操作
             */
            virtual void onStreamIO(int status, EventFlag ioe) = 0;
        
        protected:
            //异步事件发生器
            AsyncEventGenerator *eventGenerator_;
            //io 行为回调
            IOBehavior ioBehavior_;
        };

ORION_V2_NAMESPACE_END

#endif //ORIONV2_ABSTRACTASYNCSTREAM_H
